<template>
  <div class="step-bar" ref="stepBox">
    <div class="bar-inner">
      <div class="progress" ref="progress"></div>
    </div>
    <div class="ball-inner" ref="ballInner">
      <div class="ball" ref="balls" v-for="(step, index) in steps" :key="index" @click="setStepIndex(index)"
        :class="{'active': index <= currentStepIndex}">
        <span>{{step}}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    duration: {
      type: Number,
      default: 10000
    },
    steps: {
      type: Array,
      default() {
        return []
      }
    },
    playState: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 动画已经执行的时间
      excutionTime: 0,
      isPlay: this.playState,
      currentStepIndex: 0
    }
  },
  mounted() {
    setTimeout(() => {
      this._initData()
    }, 40)
  },
  methods: {
    play() {
      if (!this.playState) {
        this.isPlay = true
        this.$emit('update:playState', true)
      }
    },
    stop() {
      if (this.playState) {
        this.isPlay = false
        this.$emit('update:playState', false)
      }
    },
    next() {
      let index = this.currentStepIndex + 1
      this.setStepIndex(index)
    },
    prev() {
      let index = this.currentStepIndex - 1
      this.setStepIndex(index)
    },
    setStepIndex(index) {
      if (this.playState) {
        this.isPlay = false
      }
      let stepLength = this.steps.length
      if (!stepLength) { return }
      index = index < 0 ? 0 : index >= stepLength ? stepLength - 1 : index
      this.currentStepIndex = index
      this.$emit('changeIndex', index)
      let percent = index / stepLength
      this._updateProgress(percent)
      this.excutionTime = this.duration * index
      if (this.playState) {
        setTimeout(() => {
          this.isPlay = true
        }, 20)
      }
    },
    _initData() {
      this.$emit('changeIndex', 0)
      let totalWidth = this.$refs.ballInner.offsetWidth
      let stepLength = this.steps.length
      let oneBallProgressWidth = totalWidth / stepLength - this.$refs.balls[0].offsetWidth
      this.$refs.balls.forEach(ball => {
        ball.style.marginRight = oneBallProgressWidth + 'px'
      })
      this.totalTime = this.duration * stepLength
      this.excutionTime = this.duration * this.currentStepIndex
      this._updateProgress(this.currentStepIndex / stepLength)
    },
    _updateProgress(percent) {
      let progressBar = this.$refs.progress
      if (progressBar) {
        progressBar.style.width = `${percent * 100}%`
      }
    },
    _progressAnimate() {
      if (!this.isPlay) { return }

      let currentTime = new Date().getTime()
      this.excutionTime = currentTime - this.startTime
      let percent = this.excutionTime / this.totalTime
      if (percent > 1) {
        percent = 0
        this.startTime = currentTime
      }
      let stepIndex = Math.floor(percent * this.steps.length)
      if (this.currentStepIndex !== stepIndex) {
        this.currentStepIndex = stepIndex
        this.$emit('changeIndex', stepIndex)
      }
      this._updateProgress(percent)
      window.requestAnimationFrame(this._progressAnimate)
    }
  },
  watch: {
    isPlay(state) {
      if (state) {
        this.startTime = new Date().getTime() - this.excutionTime
        this._progressAnimate()
      }
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~common/stylus/mixin'
$color-progress=#1775F3
  .step-bar
    position: relative
    width: 100%
    height: 32px
    .bar-inner
      position: relative
      background-color: #AFBAC9
      height: 4px
      .progress
        position: absolute
        height: 100%
        background-color: $color-progress
    .ball-inner
      position: absolute
      top: -4px
      width: 100%
      display: flex
      justify-content: space-between
      .ball
        position: relative
        width: 12px
        height: 12px
        border-radius: 50%
        background-color: #7086A2
        transition .2s transform
        cursor: pointer
        span
          position: absolute
          top: 20px
          number-font(14px, #7086A2)
          left: 50%
          transform: translateX(-50%)
        &.active
          background-color: $color-progress
          span
            color: $color-progress
        &:hover
          transform: scale(1.2)
</style>
